package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/model/response"
	"guns-go/utils"
)

func GetSysDictData() (err error, sysDictDataS []model.SysDictData) {

	var dictDataSlice []model.SysDictData
	err = global.GVA_DB.Where("status <= ?", 2).Find(&dictDataSlice).Error
	return err, dictDataSlice
}

func SaveSysDictData(sysDictData *model.SysDictData, tx *gorm.DB) error {
	return tx.Create(sysDictData).Error
}

func QuerySysDictDataById(dictDataId int) (err error, dictData *model.SysDictData) {
	var sysDictData *model.SysDictData
	err = global.GVA_DB.Where("id = ?", dictDataId).Find(&sysDictData).Error
	return err, sysDictData
}

func UpdateSysDictData(sysDictData *model.SysDictData, tx *gorm.DB) error {
	return tx.Model(&sysDictData).Updates(sysDictData).Error
}

func deleteByTypeId(typeId int, status int8, tx *gorm.DB) error {
	//将所有typeId为某值的记录全部置为delete状态
	return tx.Model(model.SysDictData{}).Where("type_id = ?", typeId).Update("status", status).Error
}

func GetDictDataListByDictTypeId(dictTypeId int) (err error, dictS []map[string]interface{}) {

	var dictDataSlice []model.SysDictData
	err = global.GVA_DB.Where("type_id = ?", dictTypeId).Where("status <= ?", 2).
		Order("sort asc").Find(&dictDataSlice).Error

	if err != nil {
		return err, nil
	}

	dictSlice := make([]map[string]interface{}, 0)

	if len(dictDataSlice) > 0 {

		for _, dictData := range dictDataSlice {

			dict := make(map[string]interface{}, 0)
			dict[global.CODE] = dictData.Code
			dict[global.VALUE] = dictData.Value

			dictSlice = append(dictSlice, dict)
		}
	}

	return err, dictSlice
}

func SysDictDataPage(SysDictDataParam *request.SysDictDataParam, c *gin.Context) (err error, result *response.PageResult) {

	var SysDictDataSlice []*model.SysDictData
	db := global.GVA_DB

	if SysDictDataParam != nil {

		///根据字典类型查询
		if SysDictDataParam.TypeId != nil {
			db = db.Where("type_id = ?", SysDictDataParam.TypeId)
		}

		//根据字典类型编码模糊查询
		if SysDictDataParam.Code != "" {
			db = db.Where("code like ?", "%"+SysDictDataParam.Code+"%")
		}

		//根据字典值的内容模糊查询
		if SysDictDataParam.Value != "" {
			db = db.Where("value like ?", "%"+SysDictDataParam.Value+"%")
		}
	}
	//查询未删除的
	db = db.Where("status <> ?", 2)
	//根据排序升序排列，序号越小越在前
	db = db.Order("sort asc")

	var totalCount int64

	err = db.Find(&SysDictDataSlice).Count(&totalCount).Error

	if err != nil {
		return err, nil
	}

	pageNo, pageSize, db := utils.DefaultPage(c, db)

	err = db.Find(&SysDictDataSlice).Error

	if err != nil {
		return err, nil
	}

	return err, utils.CoverToPageResult(pageNo, pageSize, totalCount, SysDictDataSlice)
}

func SysDictDataAdd(SysDictDataParam *request.SysDictDataParam) error {

	//校验参数，检查是否存在重复的编码或者名称，不排除当前添加的这条记录
	err := checkParamByDictData(SysDictDataParam, false)

	if err != nil {
		return err
	}

	//2.构造实体
	SysDictData := new(model.SysDictData)

	err = utils.SimpleCopyProperties(SysDictData, SysDictDataParam)

	if err != nil {
		return err
	}

	var zero int8
	zero = 0

	//设置状态为启用
	SysDictData.Status = &zero

	tx := global.GVA_DB.Begin()

	//3.保存到库中
	err = SaveSysDictData(SysDictData, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SysDictDataEdit(SysDictDataParam *request.SysDictDataParam) error {

	//1.根据id查询实体
	err, SysDictData := QuerySysDictDataById(SysDictDataParam.Id)

	if err != nil {
		return err
	}

	if SysDictData.Id == 0 {
		return errors.New("字典值不存在")
	}

	//2.校验参数，是否有重复的名称和编码，排除本条记录
	err = checkParamByDictData(SysDictDataParam, true)

	if err != nil {
		return err
	}

	err = utils.SimpleCopyProperties(SysDictData, SysDictDataParam)

	if err != nil {
		return err
	}

	//不能修改状态，用修改状态接口修改状态
	SysDictData.Status = nil

	tx := global.GVA_DB.Begin()

	//3.更新记录
	err = UpdateSysDictData(SysDictData, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SysDictDataDelete(SysDictDataParam *request.SysDictDataParam) error {

	//1.根据id获取常量信息
	err, SysDictData := QuerySysDictDataById(SysDictDataParam.Id)

	if err != nil {
		return err
	}

	if SysDictData.Id == 0 {
		return errors.New("字典值不存在")
	}

	var two int8
	two = 2
	//2.设置状态为已删除
	SysDictData.Status = &two

	tx := global.GVA_DB.Begin()

	err = UpdateSysDictData(SysDictData, tx)

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

//校验参数，是否有重复的名称和编码
func checkParamByDictData(SysDictDataParam *request.SysDictDataParam, isExcludeSelf bool) error {

	id := SysDictDataParam.Id
	typeId := SysDictDataParam.TypeId
	code := SysDictDataParam.Code

	var SysDictDataSlice []*model.SysDictData

	db := global.GVA_DB
	//构建带code的查询条件
	dbCode := db.Where("type_id = ?", typeId).Where("code = ?", code).Where("status <> ?", 2)

	//如果排除自己，则增加查询条件主键id不等于本条id
	if isExcludeSelf {
		dbCode = dbCode.Where("id <> ?", id)
	}

	var countByCode int64
	err := dbCode.Find(&SysDictDataSlice).Count(&countByCode).Error

	if err != nil {
		return err
	}

	//如果存在重复的记录，抛出异常，直接返回前端
	if countByCode >= 1 {
		return errors.New("字典值编码重复，请检查code参数")
	}

	return nil
}
